package com.carey.blog.action.impl;

import java.io.IOException;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.json.JSONException;
import org.json.JSONObject;

import com.carey.blog.framework.latke.Keys;
import com.carey.blog.framework.latke.action.AbstractAction;
import com.carey.blog.framework.latke.action.ActionException;
import com.carey.blog.framework.latke.action.util.PageCaches;
import com.carey.blog.framework.latke.util.Strings;
import com.carey.blog.model.Common;
import com.carey.blog.util.PageCacheKeys;
import com.carey.blog.util.Users;

/**
 * Cache clear action.
 * 
 */
public final class ClearCacheAction extends AbstractAction {

	/**
	 * Default serial version uid.
	 */
	private static final long serialVersionUID = 1L;
	/**
	 * Logger.
	 */
	private static final Logger LOGGER = Logger
			.getLogger(ClearCacheAction.class.getName());
	/**
	 * User utilities.
	 */
	private Users userUtils = Users.getInstance();
	/**
	 * Page cache utilities.
	 */
	private PageCacheKeys pageCacheKeys = PageCacheKeys.getInstance();

	@Override
	protected Map<?, ?> doFreeMarkerAction(
			final freemarker.template.Template template,
			final HttpServletRequest request, final HttpServletResponse response)
			throws ActionException {
		throw new UnsupportedOperationException("Not supported yet.");
	}

	@Override
	protected JSONObject doAjaxAction(final JSONObject data,
			final HttpServletRequest request, final HttpServletResponse response)
			throws ActionException {
		final JSONObject ret = new JSONObject();

		final String all = data.optString("all");
		try {
			if (Strings.isEmptyOrNull(all)) { // Just clears single page cache
				final String uri = data.getString(Common.URI);
				clearPageCache(uri, request, response);
			} else { // Clears all page caches
				clearAllPageCache(request, response);
			}

			ret.put(Keys.STATUS_CODE, true);
		} catch (final Exception e) {
			LOGGER.log(Level.SEVERE, e.getMessage(), e);

			try {
				ret.put(Keys.STATUS_CODE, false);
			} catch (final JSONException ex) {
				LOGGER.log(Level.SEVERE, ex.getMessage(), ex);

				throw new ActionException(ex);
			}
		}

		return ret;
	}

	/**
	 * Clears a page cache specified by the given URI.
	 * 
	 * @param uri
	 *            the specified URI
	 * @param request
	 *            the specified http servlet request
	 * @param response
	 *            the specified http servlet response
	 * @throws ActionException
	 *             action exception
	 * @throws IOException
	 *             io exception
	 */
	public void clearPageCache(final String uri,
			final HttpServletRequest request, final HttpServletResponse response)
			throws ActionException, IOException {
		if (!userUtils.isAdminLoggedIn()) {
			response.sendError(HttpServletResponse.SC_FORBIDDEN);
			return;
		}

		String pageCacheKey = uri;
		pageCacheKey = pageCacheKeys.getPageCacheKey(uri, null);

		LOGGER.log(Level.INFO, "Clears page cache[pageCacheKey={0}]",
				pageCacheKey);

		PageCaches.remove(pageCacheKey);
	}

	/**
	 * Clears all page cache.
	 * 
	 * @param request
	 *            the specified http servlet request
	 * @param response
	 *            the specified http servlet response
	 * @throws ActionException
	 *             action exception
	 * @throws IOException
	 *             io exception
	 */
	public void clearAllPageCache(final HttpServletRequest request,
			final HttpServletResponse response) throws ActionException,
			IOException {
		//final JSONObject ret = new JSONObject();
		
		if (!userUtils.isAdminLoggedIn()) {
			response.sendError(HttpServletResponse.SC_FORBIDDEN);
			return;
		}

		PageCaches.removeAll();
	}
}
